package org.shagin.jfin.ui.budget.item.impl;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;

import javax.swing.JComboBox;
import javax.swing.JTextField;

import org.shagin.jfin.core.Debug;
import org.shagin.jfin.data.model.Account;
import org.shagin.jfin.data.model.OperationRule;
import org.shagin.jfin.ui.UI;
import org.shagin.jfin.ui.budget.item.JOperationRuleActionsPane;
import org.shagin.swing.layout.FormLayoutPanel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The Class OperationRuleView.
 * 
 * @param <T> the generic type
 */
public abstract class OperationRuleView<T extends OperationRule>
        extends
            AbstractBudgetItemView {

    private static final long serialVersionUID = 810943263972081928L;
    private static final Logger log = LoggerFactory
            .getLogger(OperationRuleView.class);

    private FormLayoutPanel pane = new FormLayoutPanel(UI.GAP);
    private JTextField title = new JTextField();
    private JComboBox<Account> accounts = new JComboBox<Account>();
    private JOperationRuleActionsPane ruleActionsPane = new JOperationRuleActionsPane();

    private ActionListener accountsActionListener;

    /**
     * Instantiates a new operation rule view.
     */
    public OperationRuleView() {
        super();
        Debug.traceEnter(log);
        setLayout(new BorderLayout());
        add(pane, BorderLayout.NORTH);
        // TODO Localize
        pane.add("Name:", title);
        pane.wrap();
        pane.add("Account:", accounts);
        add(ruleActionsPane, BorderLayout.CENTER);

        accountsActionListener = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                Debug.traceEnter(log);
                if (accounts.getSelectedItem() != null) {
                    getOperationRule().setSourceAccount(
                            (Account) accounts.getSelectedItem());
                    getOperationRule().getBudget()
                            .fireOperationRuleChangedEvent(getOperationRule());
                }
            }
        };

        title.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                Debug.traceEnter(log, title.getText());
                getOperationRule().setId(title.getText());
                getOperationRule().getBudget().fireOperationRuleChangedEvent(
                        getOperationRule());
            }
        });
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setBudgetItem(Object budgetItem) {
        Debug.traceEnter(log);
        removeEventListeners();
        super.setBudgetItem(budgetItem);
        title.setText(getOperationRule().getId());
        populateCombobox(accounts, getOperationRule().getBudget()
                .getAccountDomain().getAll());
        accounts.setSelectedItem(getOperationRule().getSourceAccount());
        ruleActionsPane.setOperationRule(getOperationRule());
        addEventListeners();
    }

    /**
     * Gets the operation rule.
     * 
     * @return the operation rule
     */
    @SuppressWarnings("unchecked")
    public T getOperationRule() {
        return (T) getBudgetItem();
    }

    /**
     * Populate combobox.
     * 
     * @param comboBox the combo box
     * @param accounts the accounts
     */
    private static void populateCombobox(JComboBox<Account> comboBox,
            List<Account> accounts) {
        comboBox.removeAllItems();
        for (Account account : accounts) {
            comboBox.addItem(account);
        }
    }

    /**
     * Adds the event listeners.
     */
    private void addEventListeners() {
        accounts.addActionListener(accountsActionListener);
    }

    /**
     * Removes the event listeners.
     */
    private void removeEventListeners() {
        accounts.removeActionListener(accountsActionListener);
    }
}
